

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.Writer;

public final class DatabaseDriver {

	/**
	 * storeID identifies the store (folder name) tableID identifies the actual
	 * table (file name)
	 */
	private String storeID, tableID;
	/**
	 * Contents of the database as a string
	 */
	private String databaseContents;

	/**
	 * Gets the contents of the database as a string. Keeps it nice and generic
	 * so the actual implementation of the database is left up to the user
	 *
	 * @return The database contents as a string
	 */
	public String getDatabaseContents() {
		return databaseContents;
	}

	/**
	 * Sets the contents of the database from a string
	 *
	 * @param databaseContents
	 *            The contents to set
	 */
	public void setDatabaseContents(String databaseContents) {
		this.databaseContents = databaseContents;
	}

	/**
	 * Constructs a generic driver given a storeID and tableID
	 *
	 * @param storeID
	 *            The storeID (folder name)
	 * @param tableID
	 *            The tableID (file name)
	 */
	public DatabaseDriver(String storeID, String tableID) {
		this.storeID = storeID;
		this.tableID = tableID;
		createClientDB(); // Creates it if it doesn't already exists
		LoadDatabase(); // Loads the database from file
	}

	/**
	 * Reads the database from file, and then puts it in databaseContents Didn't
	 * rewrite this to remove the parameters because I didn't want to rewrite
	 * Thomas' code when it did the job
	 */
	private void LoadDatabase() {
		readFromFile(tableID, storeID);
	}

	/**
	 * Writes the database to disc
	 */
	protected void SaveDatabase() {
		writeToFile(databaseContents, tableID, storeID);
	}

	/**
	 * Makes the directory for the store
	 *
	 * @param dirname
	 *            Directory name
	 * @return Status (0 for success, -1 for fail)
	 */
	private int createDir(String dirname) {
		try {
			boolean success = (new File(dirname).mkdir());
			if (success) {
				return 0;
			} else {
				return -1;
			}
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to delete a sub-directory at the current directory of name
	 * 'dirname'
	 *
	 * @param dirname
	 *            Name of directory to be deleted
	 * @return Status (0 for success, -1 for fail)
	 */
	private int deleteDir(String dirname) {
		try {
			boolean success = (new File(dirname).delete());
			if (success) {
				return 0;
			} else {
				return -1;
			}
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to create a text file named by 'filename' in the directory
	 * given by 'dirname'
	 *
	 * @param filename
	 *            Name of file to created
	 * @param dirname
	 *            Name of directory where file is to be created
	 * @return Status (0 for success, -1 for fail)
	 */
	private int createFile(String filename, String dirname) {
		try {
			createDir(dirname);
			File f = new File(dirname, filename + ".txt");
			if (!f.exists()) {
				f.createNewFile();
				return 0;
			} else {
				return -1;
			}
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to delete a text file named by 'filename' in the directory
	 * given by 'dirname'
	 *
	 * @param filename
	 *            Name of file to be deleted
	 * @param dirname
	 *            Name of directory containing file to be deleted
	 * @return Status (0 for success, -1 for fail)
	 */
	private int deleteFile(String filename, String dirname) {
		try {
			File f = new File(dirname, filename + ".txt");
			if (f.exists()) {
				f.delete();
				deleteDir(dirname);
				return 0;
			} else {
				return -1;
			}
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to overwrite a given file of 'filename'.txt
	 *
	 * @param data
	 *            Data to overwrite file with
	 * @param filename
	 *            Name of file to be overwritten
	 * @param dirname
	 *            Name of directory containing file to be overwritten
	 * @return Status (0 for success, -1 for fail)
	 */
	private int overwriteFile(String data, String filename, String dirname) {
		try {
			createFile(filename, dirname);
			Writer output = new BufferedWriter(new FileWriter("./" + dirname
					+ "/" + filename + ".txt"));
			output.write(data);
			output.close();
			return 0;
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to append data to a given file of 'filename'.txt
	 *
	 * @param filename
	 *            Name of file to write to
	 * @param dirname
	 *            Name of directory where file is located
	 * @return Status (0 for success, -1 for fail)
	 */
	private int writeToFile(String data, String filename, String dirname) {
		try {
			createFile(filename, dirname);
			Writer output = new BufferedWriter(new FileWriter("./" + dirname
					+ "/" + filename + ".txt", true));
			output.write(data + "\n");
			output.close();
			return 0;
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to read data from a file given a unique ID
	 *
	 * @param filename
	 *            Name of file to be read
	 * @param dirname
	 *            Name of directory where file to be read is located
	 * @return Status (0 for success, -1 for fail)
	 */
	private int readFromFile(String filename, String dirname) {
		try {
			FileInputStream fstream = new FileInputStream("./" + dirname + "/"
					+ filename + ".txt");
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			databaseContents = "";
			while ((strLine = br.readLine()) != null) {
				databaseContents = "";
			}
			in.close();
			return 0;
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * Method called to create client database. Creates a directory called
	 * clientID and a file for the services data to go into. On success 0 is
	 * returned, if files already exist the -1 is returned
	 *
	 * @return Status (0 for success, -1 for fail)
	 */
	private int createClientDB() {
		try {
			int success = createFile(tableID, storeID);
			if (success == 0) {
				return 0;
			} else {
				return -1;
			}
		} catch (Exception e) {
			return -1;
		}
	}
}

